/*
 * From http://netbeans.dzone.com/how-to-create-dropdowns-in-nb
 */
package org.tintuna.cca.property;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorSupport;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import org.openide.explorer.propertysheet.ExPropertyEditor;
import org.openide.explorer.propertysheet.InplaceEditor;
import org.openide.explorer.propertysheet.PropertyEnv;
import org.openide.explorer.propertysheet.PropertyModel;
import org.openide.nodes.PropertySupport;
import org.tintuna.cca.data.Row;
import org.tintuna.cca.node.RowNode;

/**
 *
 * @author bsmith
 */
public class CategoryProperty extends PropertySupport.ReadWrite<String> {

    Row row;

    public CategoryProperty(Row row) {
        super(RowNode.CATEGORIES_PROPERTY, String.class, "Transaction categories", "The categories of the transaction");
        this.row = row;
    }

    @Override
    public String getValue() throws IllegalAccessException, InvocationTargetException {
        return row.getCategory();
    }

    @Override
    public void setValue(String t) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public PropertyEditor getPropertyEditor() {
        return new CategoryPropertyEditorSupport(row);
    }

    private class CategoryPropertyEditorSupport extends PropertyEditorSupport implements ExPropertyEditor, InplaceEditor.Factory {

        private final Row row;
        private Inplace ed = null;

        private CategoryPropertyEditorSupport(Row row) {
            this.row = row;
            ed = new Inplace(row);
        }

        @Override
        public String getAsText() {
            String s = (String) getValue();
            if (s == null) {
                return (String) ed.getValue(0);
            }
            return s;
        }

        @Override
        public void setAsText(String s) {
            setValue(s);
        }

        @Override
        public void attachEnv(PropertyEnv env) {
            env.registerInplaceEditorFactory(this);
        }

        @Override
        public InplaceEditor getInplaceEditor() {
            if (ed == null) {
                ed = new Inplace(row);
            }
            return ed;
        }
    }

    public class Inplace implements InplaceEditor, OurPropertyEditor {

        private final JComboBox comboBox = new JComboBox();
        private PropertyEditor editor = null;
        private final Row row;

        private Inplace(final Row row) {
            this.row = row;
            comboBox.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    row.setCategory(comboBox.getModel().getSelectedItem().toString());
                }
            });
        }

        @Override
        public void connect(PropertyEditor propertyEditor, PropertyEnv env) {
            editor = propertyEditor;
            reset();
        }

        @Override
        public JComponent getComponent() {
            return comboBox;
        }

        @Override
        public void clear() {
            editor = null;
            model = null;
        }

        @Override
        public Object getValue() {
            comboBox.repaint();
            comboBox.updateUI();
            ((JComponent) comboBox.getParent()).requestFocus();
            comboBox.updateUI();
            comboBox.repaint();
            return comboBox.getSelectedItem();
        }

        @Override
        public void setValue(Object object) {
            comboBox.setSelectedItem(object);
            comboBox.repaint();
            comboBox.updateUI();
            ((Row) object).setCategory(comboBox.getSelectedItem().toString());
            ((JComponent) comboBox.getParent()).requestFocus();
        }

        /**
         * @param index
         * @return the indexeth item in the combo box
         */
        @Override
        public Object getValue(int index) {
            return comboBox.getItemAt(index);
        }
        
        @Override
        public boolean supportsTextEntry() {
            return true;
        }

        @Override
        public void reset() {
            comboBox.addItem("None defined");
            comboBox.addItem("Utility");
            comboBox.addItem("Telecommunications");
            comboBox.addItem("Entertainment - Food");
            comboBox.addItem("Entertainment - Drink");
            comboBox.addItem("Entertainment - Live");
            comboBox.addItem("Grocery");
            comboBox.addItem("Department");
            comboBox.addItem("Computer");
            String str = (String) editor.getValue();
            if (str != null) {
                comboBox.setSelectedItem(str);

            }
        }

        @Override
        public KeyStroke[] getKeyStrokes() {
            return new KeyStroke[0];
        }

        @Override
        public PropertyEditor getPropertyEditor() {
            return editor;
        }

        @Override
        public PropertyModel getPropertyModel() {
            return model;
        }
        private PropertyModel model;

        @Override
        public void setPropertyModel(PropertyModel propertyModel) {
            this.model = propertyModel;
        }

        @Override
        public boolean isKnownComponent(Component component) {
            return component == comboBox || comboBox.isAncestorOf(component);
        }

        @Override
        public void addActionListener(ActionListener actionListener) {
            //do nothing - not needed for this component
        }

        @Override
        public void removeActionListener(ActionListener actionListener) {
            //do nothing - not needed for this component
        }
    }
}
